/*
 amount.go
 Created by hupfei on 2019-06-29
*/

package v1

import (
	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
	"unicode/utf8"
	"zimuzu_cvn_web_api/config"
	"zimuzu_cvn_web_api/model"
	"zimuzu_cvn_web_api/pkg/e"
	"zimuzu_cvn_web_api/pkg/errno"
	"zimuzu_cvn_web_api/router/api"
	"zimuzu_cvn_web_api/router/api/app/middleware"
	"zimuzu_cvn_web_api/service"
)

type AmountAPI struct {
}

func (a AmountAPI) Name() string {
	return "amount API"
}

func (a AmountAPI) Bind() {
	amountAPI := config.C.Router.Group("/v1/app/amount", middleware.TrackLog(), middleware.AuthMiddleware())
	{
		amountAPI.GET("cvntLog", cvntLog)
		amountAPI.GET("logDetail", logDetail)
		amountAPI.GET("unavailableInfo", unavailableInfo)
		amountAPI.GET("transfer/lastAddress", lastAddress)
		amountAPI.GET("transfer/addressList", addressList)
		amountAPI.GET("transfer/updateAddress", updateAddress)
		amountAPI.GET("transfer/deleteAddress", deleteAddress)
	}
}

/*
 * @ Author: hupfei
 * @ Description: 资产列表
 **/
type cvnLogParams struct {
	model.PageParams
	Source int `form:"source"`
	Type   int `form:"type"` //0 cvnt 1 usdt
}

func cvntLog(c *gin.Context) {
	var params cvnLogParams
	params.PageParams = model.NewDefaultPageParams()
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}

	uid, _ := service.GetUserIdByRequest(c)
	res, err := service.GetAccountLogListForApp(uid, params.Type, params.Source, params.Per, params.Page)
	if err != nil {
		api.SendResponse(c, errors.New("查询资产列表失败"), nil)
		return
	}
	e.Log("info", "请求用户流水记录成功")
	errno.OK.Info = "返回资产列表成功"
	api.SendResponse(c, errno.OK, res)
}

/*
 * @ Author: hupfei
 * @ Description: 资产详情
 **/
type cvntLogDetailParams struct {
	Id   int64 `form:"id" binding:"required"`
	Type int   `form:"type"` //0 cvnt 1 usdt
}

func logDetail(c *gin.Context) {
	var params cvntLogDetailParams
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}

	res, err := service.GetLogDetail(params.Id, params.Type)
	if err != nil {
		api.SendResponse(c, errors.New("查询资产详情失败"), nil)
		return
	}
	errno.OK.Info = "返回资产详情成功"
	api.SendResponse(c, errno.OK, res)
}

/*
 * @ Author: hupfei
 * @ Description: 不可用额度明细
 **/
func unavailableInfo(c *gin.Context) {
	var params = model.NewDefaultPageParams()
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	uid, _ := service.GetUserIdByRequest(c)

	data, err := service.UnavailableInfoList(uid, params.Page, params.Per)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	errno.OK.Info = "返回不可用额度明成功"
	api.SendResponse(c, errno.OK, data)
	return
}

/*
 * @ Author: hupfei
 * @ Description: 3.5.10 上一次转账地址
 **/
func lastAddress(c *gin.Context) {
	var params model.PageParams
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}

	uid, _ := service.GetUserIdByRequest(c)
	re, err := model.SearchLastTransferAddress(uid)
	errno.OK.Info = "成功"
	api.SendResponse(c, errno.OK, re)
	return
}

/*
 * @ Author: hupfei
 * @ Description: 3.5.11 转账地址列表
 **/
type addressListParams struct {
	model.PageParams
	Key string `form:"key"`
}

func addressList(c *gin.Context) {
	var params addressListParams
	params.PageParams = model.NewDefaultPageParams()
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}

	uid, _ := service.GetUserIdByRequest(c)
	data, err := model.SearchTransferAddressList(uid, params.Key, params.Page, params.Per)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	errno.OK.Info = "返回转账地址列表成功"
	api.SendResponse(c, errno.OK, data)
	return
}

/*
 * @ Author: hupfei
 * @ Description: 3.5.12 添加、更新转账地址
 **/
type updateAddressParams struct {
	Name    string `form:"name" binding:"required"`
	Address string `form:"address" binding:"required"`
	Id      int64  `form:"id"`
	U       string `form:"u" binding:"required"`
}

func updateAddress(c *gin.Context) {
	var params updateAddressParams
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}

	uid, _ := service.GetUserIdByRequest(c)
	//去校验 u 是否正确
	ok := service.IsPayPasswordChecked(uid, params.U)
	if !ok {
		api.SendResponse(c, errno.PayPasswordCheckExpire, nil)
		return
	}

	//转账地址是否合法
	coinType := e.COIN_TYPE_ERC20
	if ok := e.CheckWalletFormat(params.Address, coinType); !ok {
		api.SendResponse(c, errno.ErrWalletFormat, nil)
		return
	}

	//地址备注只能2-10字符
	if utf8.RuneCountInString(params.Name) < 2 || utf8.RuneCountInString(params.Name) > 10 {
		api.SendResponse(c, errors.New("备注长度必须是2至10位"), nil)
		return
	}

	if params.Id > 0 {
		//修改地址
		//记录是否存在
		exist := model.TransferAddressExistById(params.Id)
		if !exist {
			api.SendResponse(c, errno.RecordError, nil)
			return
		}

		err = model.UpdateTransferAddress(params.Id, params.Name, params.Address)
		if err != nil {
			api.SendResponse(c, errno.UpdateDataErr, nil)
			return
		}

		errno.OK.Info = "修改成功"
		api.SendResponse(c, errno.OK, nil)
		return
	}

	//转账地址是否添加过
	exist := model.TransferAddressExistByaddress(uid, params.Address)
	if exist {
		api.SendResponse(c, errors.New("您已经添加过该地址"), nil)
		return
	}

	id, err := model.InsertTransferAddress(uid, params.Name, params.Address)
	if err != nil {
		api.SendResponse(c, errno.DbError, nil)
		return
	}
	re := map[string]interface{}{
		"id": id,
	}
	errno.OK.Info = "添加转账地址成功"
	api.SendResponse(c, errno.OK, re)
	return
}

/*
 * @ Author: hupfei
 * @ Description: 3.5.13 删除转账地址
 **/
type deleteAddressParams struct {
	Id int64 `form:"id" binding:"required"`
}

func deleteAddress(c *gin.Context) {
	var params deleteAddressParams
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}

	//记录是否存在
	exist := model.TransferAddressExistById(params.Id)
	if !exist {
		api.SendResponse(c, errno.RecordError, nil)
		return
	}

	err = model.DeleteTransferAddress(params.Id)
	if err != nil {
		api.SendResponse(c, errno.DbError, nil)
		return
	}

	errno.OK.Info = "删除成功"
	api.SendResponse(c, errno.OK, nil)
	return
}
